#include "downloader.h"
#include <QFileInfo>
#include <QTimer>
#include <QMessageBox>
#include <QDir>
#include <QApplication>

Downloader::Downloader(QObject *parent)
     : QObject(parent), downloadedCount(0), totalCount(0)
{
}

void Downloader::append(DownloadTask *task)
{
    if (downloadQueue.isEmpty()){
        QTimer::singleShot(0, this, SLOT(startNextDownload()));
    }

    downloadQueue.enqueue(task);
    ++totalCount;
}

QString Downloader::saveFileName(const QString &rename, const QString &savePath)
{
    QString fileName = savePath + "/" + rename;
    if (QFile::exists(fileName)) {
        int i = 0;
        while (QFile::exists(savePath + "/" + QString::number(i) + rename)){
            ++i;
        }
        fileName = savePath + "/" + QString::number(i) + rename;
    }
    return fileName;
}

void Downloader::startNextDownload()
{
    if (downloadQueue.isEmpty()) {
        printf("%d/%d files downloaded successfully\n", downloadedCount, totalCount);
        emit finished();
        return;
    }

    DownloadTask *task = downloadQueue.dequeue();
    QUrl url = task->url();
    currentFilePath = task->path() + task->rename();

    QString filename = saveFileName(task->rename(), task->path());
    output.setFileName(filename);
    if (!output.open(QIODevice::WriteOnly)) {
        const QString title = "Error!";
        const QString text = "Problem opening save file " + filename + " for download " + url.toString();
        //QMessageBox *mb = new QMessageBox(QMessageBox::Critical, title, text, QMessageBox::Yes, this);
        //mb->exec();

        startNextDownload();
        return;                 // skip this download
    }

    QNetworkRequest request(url);
    currentDownload = manager.get(request);
    connect(currentDownload, SIGNAL(downloadProgress(qint64,qint64)),
            SLOT(downloadProgress(qint64,qint64)));
    connect(currentDownload, SIGNAL(finished()),
            SLOT(downloadFinished()));
    connect(currentDownload, SIGNAL(readyRead()),
            SLOT(downloadReadyRead()));

    // prepare the output
    //printf("Downloading %s...\n", url.toEncoded().constData());
    downloadTime.start();
}

void Downloader::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
    // calculate the download speed
    double speed = bytesReceived * 1000.0 / downloadTime.elapsed();
    QString unit;
    if (speed < 1024) {
        unit = "bytes/sec";
    } else if (speed < 1024*1024) {
        speed /= 1024;
        unit = "kB/s";
    } else {
        speed /= 1024*1024;
        unit = "MB/s";
    }

    double res = 100*(double)bytesReceived/bytesTotal;
    emit progressChanged(currentFilePath, res);

}

void Downloader::downloadFinished()
{
    output.close();

    if (currentDownload->error()) {
        // download failed
        //fprintf(stderr, "Failed: %s\n", qPrintable(currentDownload->errorString()));
    } else {
        //printf("Succeeded.\n");
        ++downloadedCount;
    }

    currentDownload->deleteLater();
    startNextDownload();
}

void Downloader::downloadReadyRead()
{
    output.write(currentDownload->readAll());
}
